from datetime import datetime, timedelta, time, date

# 计算请假占用的工作时间, 通义给出的方案，支持跨天的请假时间计算，定义了工作时间段
# 工作时间段定义（如 07:30-11:30, 13:00-17:00, 19:00-22:00）
# 请假时间段定义（如 10:30-21:00）
# 自动计算请假时间中与工作时间段重叠的部分
# 支持跨天请假（比如从 23:00 到次日 02:00）


# 构建带日期的时间对象
def make_datetime(date_str, time_obj):
    return datetime.strptime(date_str, "%Y-%m-%d") + timedelta(
        hours=time_obj.hour, minutes=time_obj.minute
    )


# 计算两个时间段的交集时长（分钟）
def get_overlap_minutes(leave_start, leave_end, work_start, work_end):
    overlap_start = max(leave_start, work_start)
    overlap_end = min(leave_end, work_end)

    if overlap_start >= overlap_end:
        return 0

    return int((overlap_end - overlap_start).total_seconds() // 60)


# 主函数：计算请假占用的工作时间（跳过周末 + 节假日）
def calculate_work_time_overlap(leave_start, leave_end, work_periods, holidays):
    total_minutes = 0

    current_day = leave_start.date()
    end_day = leave_end.date()

    while current_day <= end_day:
        # 判断是否为周末（周六 or 周日）
        # if current_day.weekday() >= 5:  # 5=Saturday, 6=Sunday
        if current_day.weekday() in [0, 1]:  # 表示周一和周二为休息日
            current_day += timedelta(days=1)
            continue

        # 判断是否为节假日
        if current_day in holidays:
            current_day += timedelta(days=1)
            continue

        # 遍历当天的工作时间段
        for wp in work_periods:
            wp_start, wp_end = wp

            dt_start = make_datetime(str(current_day), wp_start)
            dt_end = make_datetime(str(current_day), wp_end)

            if dt_end < leave_start or dt_start > leave_end:
                continue  # 无交集

            overlap = get_overlap_minutes(leave_start, leave_end, dt_start, dt_end)
            total_minutes += overlap

        current_day += timedelta(days=1)

    return total_minutes


# 示例用法
if __name__ == "__main__":
    # 设置请假时间段（可跨天）
    leave_start = datetime(2025, 5, 29, 23, 0)  # 星期四晚上
    leave_end = datetime(2025, 6, 1, 2, 0)  # 跨到星期一凌晨

    # 定义每天的工作时间段（time 对象）
    work_periods = [
        (time(7, 30), time(11, 30)),
        (time(13, 0), time(17, 0)),
        (time(19, 0), time(22, 0)),
    ]

    # 定义节假日列表（date 对象）
    holidays = {
        date(2025, 5, 29),  # 假设是节日
        # date(2025, 6, 1),  # 假设是调休周末（虽然是周日）
    }

    # 计算总工作时间内的请假时长
    total_minutes = calculate_work_time_overlap(
        leave_start, leave_end, work_periods, holidays
    )
    total_hours = round(total_minutes / 60.0, 2)

    print(
        f"\n请假期间占用的工作时间段共计: {total_minutes} 分钟（即 {total_hours} 小时）"
    )
